﻿using Furion.DatabaseAccessor.Extensions;
using Furion.LinqBuilder;
using Furion.Localization;
using ST.Torch.WebApi.Application.System.Dtos;
using ST.Torch.WebApi.Application.System.Services;
using ST.Torch.WebApi.Application.Utils.Services;
using ST.Torch.WebApi.Core.Entities.System;
using ST.Torch.WebApi.Core.Manage.Cache.Dto;
using ST.Torch.WebApi.Core.Manager;
using ST.Torch.WebApi.Core.Utils;
using Mapster.Utils;
using MiniExcelLibs;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace ST.Torch.WebApi.Application.System
{

    /// <summary>
    /// 系统服务接口
    /// </summary>
    [AppAuthorize]
    public class UtilExcelAppService : IDynamicApiController
	{
		private readonly UtilExcelService _UtilExcelService;
		private readonly SYSMenuService _SYSMenuService;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly ICacheManage _ICacheManage;
        

        public UtilExcelAppService(UtilExcelService UtilExcelService, SYSMenuService sYSMenuService, IHttpContextAccessor httpContextAccessor, ICacheManage cacheManage)
        {
            _UtilExcelService = UtilExcelService;
            _SYSMenuService = sYSMenuService;
            _httpContextAccessor = httpContextAccessor;
                _ICacheManage = cacheManage;
        }


        [HttpPost]
		public async Task<PagedList<UtilExcelListDto>> GetDataPagedList([FromForm] PageReq req)
		{
			Expression<Func<UtilExcel, bool>> predicate = u => true;
            predicate=predicate.AndIf(!string.IsNullOrEmpty(req.key),u=>u.Column1.Contains(req.key) || u.Column2.Contains(req.key));
			
			var dataList= await _UtilExcelService.QueryPageAsync(predicate, req);
			PagedList<UtilExcelListDto> resultList = dataList.Adapt<PagedList<UtilExcelListDto>>();

			return resultList;
		}
        [HttpPost]
        public async Task<UtilExcelListDto> Single([FromForm] Guid Id)
        {
           
           var entity= await _UtilExcelService.SingleAsync(u=>u.Id==Id);
            UtilExcelListDto resultData = entity.Adapt<UtilExcelListDto>();
			return resultData;

        }
        [HttpPost]
        public async Task Insert([FromForm] UtilExcelDto model)
        {
            for (int i = 0; i < 100; i++)
            {
                UtilExcel entity = model.Adapt<UtilExcel>();
                entity.Column1 = i.ToString();
                await _UtilExcelService.InsertAsync(entity);
            }
        }
		[HttpPost]
		public async Task Update([FromForm] UtilExcelListDto model)
		{
			
			var entity=await _UtilExcelService.SingleAsync(u => u.Id == model.Id);
			entity.Column1=model.Column1;
			entity.Column2=model.Column2;
			entity.Column3=model.Column3;
			entity.Column4=model.Column4;
			entity.Column5=model.Column5;

            await _UtilExcelService.UpdateAsync(entity);
		}
		[HttpPost]
		public async Task DeleteAsync([FromForm] Guid Id)
		{
			var entity = await _UtilExcelService.SingleAsync(u => u.Id == Id);
			await _UtilExcelService.DeleteAsync(entity);
		}

        [HttpPost]
        public async Task DeleteBatchAsync([FromForm] List<Guid> Ids)
        {
            var entitys = await _UtilExcelService.QueryAsync(u => Ids.Contains(u.Id));
            foreach (var entity in entitys)
            {
                await _UtilExcelService.DeleteAsync(entity);
            }
        }


        /// <summary>
        /// 导入数据通用方法
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        [HttpPost, NonUnify,ManualCommit]
        [RequestSizeLimit(100_000_000)]
        public async Task<dynamic> ImportExcelfiles(string filename)
        {

            try
            {

                if (_httpContextAccessor.HttpContext.Request.Form.Files.Count() == 0) return null;
                if (string.IsNullOrEmpty(filename))
                {
                    filename = "Default";
                }
                string AutoFileName = _httpContextAccessor.HttpContext.Request.Form["AutofileName"];//给文件命名预留
                //文件的原始名称
                IFormFile UploadFile = _httpContextAccessor.HttpContext.Request.Form.Files[0];
                string FileOriginName = UploadFile.FileName;
                string fileSaveRootDir = "/uploads/file/" + filename;
                //string fileSaveRootDir = "/uploads/file/" + "Default";
                //生成文件的名称
                string Extension = Path.GetExtension(FileOriginName);//获取文件的源后缀
                                                                     //读取办公管理文件保存的模块的根目录
                string fileSaveDir = "";
                //文件保存的相对文件夹(保存到wwwroot目录下)
                string absoluteFileDir = fileSaveRootDir + "/" + fileSaveDir;
                //文件保存的路径(应用的工作目录+文件夹相对路径);
                string fileSavePath = Environment.CurrentDirectory + "/wwwroot/" + absoluteFileDir;
                //string fileSavePath = Environment.CurrentDirectory + "" + absoluteFileDir;
                if (!Directory.Exists(fileSavePath))
                {
                    Directory.CreateDirectory(fileSavePath);
                }
                if (string.IsNullOrEmpty(Extension))
                {
                    throw new Exception("文件上传的原始名称好像不对哦，没有找到文件后缀");
                }
                //string fileName = Guid.NewGuid().ToString() + Extension;//通过uuid和原始后缀生成新的文件名
                string fileName = AutoFileName + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + Extension;//通过uuid和原始后缀生成新的文件名
                if (string.IsNullOrEmpty(AutoFileName))
                {
                    fileName = Guid.NewGuid().ToString() + Extension;//通过uuid和原始后缀生成新的文件名
                }
                //最终生成的文件的相对路径（xxx/xxx/xx.xx）
                string finalyFilePath = fileSavePath + "/" + fileName;
                //打开上传文件的输入流
                Stream stream = UploadFile.OpenReadStream();
                //开始保存拷贝文件
                FileStream targetFileStream = new FileStream(finalyFilePath, FileMode.OpenOrCreate);
                await stream.CopyToAsync(targetFileStream);
                stream.Close();
                await stream.DisposeAsync();

                #region 数据处理
                var TTdata =MiniExcelUtil.GetDataList(targetFileStream);
                Progressbar progress = new Progressbar();
                
                progress.Total = TTdata.Count;
                string Ckey = string.Format(Progressbar.key, AutoFileName);
                var repository = _UtilExcelService.GetRepository();

                repository.Database.BeginTransaction();
                foreach (var item in TTdata)
                {
                    /*
                    string C1 = item.Column1;
                    string C2 = item.Column2;
                    string C3 = item.Column3;
                    string C4 = item.Column4;
                    string C5 = item.Column5;
                    UtilExcel entity = new UtilExcel();
                    entity.Column1 = C1;
                    entity.Column2 = C2;
                    entity.Column3 = C3;
                    entity.Column4 = C4;
                    entity.Column5 = C5;
                    */
                    List<string> vals = new List<string>();
                    foreach (KeyValuePair<string, object> col in item)
                    {
                        string key = col.Key;//属性
                        string val = col.Value.ToString();//值
                        vals.Add(val);
                        if (!string.IsNullOrWhiteSpace(col.Value.ToString()))
                        {

                        }
                    }
                    UtilExcel entity = new UtilExcel();
                    entity.Column1 = vals[0];
                    entity.Column2 = vals[1];
                    entity.Column3 = vals[2];
                    entity.Column4 = vals[3];
                    entity.Column5 = vals[4];

                    progress.CurrentIndex++;

                    //await Task.Delay(500);
                    var data = await _ICacheManage.GetAsync<Progressbar>(Ckey);
                    if (data == null)
                    {
                        await _ICacheManage.SetAsync<Progressbar>(Ckey, progress, 60);

                    }
                    else
                    {
                        if (data.IsCancel)
                        {
                            await repository.Database.RollbackTransactionAsync();
                            targetFileStream.Close();
                            await targetFileStream.DisposeAsync();
                            File.Delete(finalyFilePath);
                            return new
                            {
                                code = 201,
                                msg = "已取消",
                                data = absoluteFileDir + fileName

                            };
                        }
                        else
                        {
                            await _ICacheManage.SetAsync<Progressbar>(Ckey, progress, 60);
                        }

                    }

                    await repository.InsertAsync(entity);

                }
                
                //提交事务
                await repository.Database.CommitTransactionAsync();
                await repository.SaveNowAsync();

                #endregion
                targetFileStream.Close();
                await targetFileStream.DisposeAsync();
                File.Delete(finalyFilePath);
                return new
                {
                    code = 200,
                    msg = "上传成功",
                    data = absoluteFileDir + fileName

                };


            }
            catch (Exception e)
            {
                return new
                {
                    code = 500,
                    msg = e,
                    data = ""
                };
            }
        }
        /// <summary>
        /// 导出机组记录Excel
        /// </summary>
        /// <returns></returns>
        [HttpGet, QueryParameters, NonUnify]
        public async Task<dynamic> ExPortExcel(string key)
        {
            Expression<Func<UtilExcel, bool>> predicate = u => true;
            predicate = predicate.AndIf(!string.IsNullOrEmpty(key), u => u.Column1.Contains(key) || u.Column2.Contains(key));

            var dataList = await _UtilExcelService.QueryAsync(predicate);
            var ExData = dataList.Adapt<List<UtilExcelDto>>();
            var memoryStream = new MemoryStream();
            memoryStream.SaveAs(ExData);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return new FileStreamResult(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
            {
                FileDownloadName = "Test"+DateTime.Now.ToString("HHmmss")+".xlsx"
            };


        }

        [HttpPost]
        public async Task<string> GetProgressPercent([FromForm] string key, [FromForm]bool IsCancel)
        {
            string Ckey = string.Format(Progressbar.key, key);
            var data = await _ICacheManage.GetAsync<Progressbar>(Ckey);
            if (IsCancel&& data!=null)
            {
                data.IsCancel = true;
                await _ICacheManage.SetAsync<Progressbar>(Ckey, data,60);
                return "";
            }
           
            if (data != null)
            {
                return data.GetPercent;
            }
            else {
                return "0";
            }
        }



    }

}
